/**
 * Copyright (c) 2007, Softamis, http://soft-amis.com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Alexey Luchkovsky
 * E-mail: jsoner@soft-amis.com
 *
 * Version: 1.24
 * Last modified: 06/06/2007
 */

var jTools = new Jsoner();

var json = {employee:{gid:102, companyID:121, defaultActionID:444,
						names:{firstName:"Stive", middleInitial:"Jr",lastName:"Martin"},
						address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
						job:{departmentID:102,jobTitleID:100,hireDate:"1\/02\/2000",terminationDate:"1\/12\/2007"},
						contact:{phoneHome:"12-123-2133", beeper:"5656",email1:"info@soft-amis.com",
						fax:"21-321-23223",phoneMobile:"32-434-3433",phoneOffice:"82-900-8993"},
						login:{employeeID:"eID102",password:"password",superUser:true,lastLoginDate:"1\/12\/2007",
					  text:"text", regexp:/^mmm/, date: new Date() },
						comment:{PCDATA:"comment"},
						roles:[{role:102},{role:103}]}};

var json3 = {employee:{gid:105, companyID:121, defaultActionID:444,
						names:{firstName:"Stive", middleInitial:"Jr",lastName:"Martin"},
						address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
						job:{departmentID:102,jobTitleID:100,hireDate:"1\/02\/2000",terminationDate:"1\/12\/2007"},
						contact:{phoneHome:"12-123-2133", beeper:"5656",email1:"info@soft-amis.com",
						fax:"21-321-23223",phoneMobile:"32-434-3433",phoneOffice:"82-900-8993"},
						login:{employeeID:"eID102",password:"password",superUser:true,lastLoginDate:"1\/12\/2007",
					  text:"text", regexp:/^mmm/, date: new Date() },
						comment:{PCDATA:"comment"},
						roles:[{role:105}]}};

var items = {items:[
{employee:{gid:104, companyID:131,
	names:{firstName:"Mikie", middleInitial:"Jr",lastName:"Do"},
	address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
	job:{departmentID:102,jobTitleID:100},
	contact:{phoneHome:"12-123-2133", beeper:"56", email:"mike@yahoo.com"},
	login:{employeeID:"eID101",password:"password",superUser:true},
	roles:[{role:102},{role:103}]}},
{employee:{gid:105, companyID:131,
	names:{firstName:"Nick", lastName:"Martin"},
	address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
	job:{departmentID:102,jobTitleID:100},
	contact:{phoneHome:"12-123-2133", beeper:"5656", email:"nick@yahoo.com"},
	login:{employeeID:"eID103",password:"password",superUser:true},
	roles:[{role:102},{role:103}]}},
{employee:{gid:106, companyID:131,
	names:{firstName:"John", middleInitial:"Jr",lastName:"Smith"},
	address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
	job:{departmentID:102,jobTitleID:100},
	contact:{phoneHome:"12-123-2133", beeper:"5656", email:"john@yahoo.com"},
	login:{employeeID:"eID104",password:"password",superUser:true},
	employee:{ gid:1106, names:{firstName:"Maxime", middleInitial:"De",lastName:"Lux"} },
	roles:[{role:102},{role:103}]}},
{employee:{gid:107, companyID:131, defaultActionID:444,
	names:{firstName:"Mark", lastName:"Martin"},
	address:{city:"Albany",state:"NY",zipCode:"14410-585",addreess:"41 State Street"},
	job:{departmentID:102,jobTitleID:100},
	contact:{phoneHome:"12-123-2133", beeper:"5656", email:"mark.com"},
	login:{employeeID:"eID105",password:"password",superUser:true},
	roles:[{role:102},{role:105}]}}
				]};


var companies = {companies:[{text:"Oracle Corporation",value:119},
														{text:"Symantec Corporation",value:120},
														{text:"SoftAMIS Corporation",value:121},
														{text:"Konami Corporation",value:122},
														{text:"BEA Systems, Inc.",value:123}]};

var departments = {departments:[{text:"Research Department",value:101},
																{text:"Software Department",value:102},
																{text:"Management Group",value:103}]};

var corpMap = jTools.jsonToMap(companies.companies, "value", "text");
var deptMap = jTools.jsonToMap(departments.departments, "value", "text");

var json2 = {employee:{names:{firstName:"Mickey",middleInitial:"",lastName:"Mouse"}} };

var contact = {phoneHome:"999-999-99", beeper:"979", email1:"john@unknown.net"};

var jPattern =  { "employee.gid":{div:{span:null, input:{"type":"hidden"}} },
				          "employee.names.firstName":{div:{input:{size:"20"} } },
				          "employee.names.middleInitial":{div:{input:{size:"5"} } },
				          "employee.companyID":{div:{span:{text:"Company:"}, input:null, "select":{"class":"json_input", option:companies.companies} } },
	                "employee.job.departmentID":{div:{span:{text:"Department:"}, input:null, "select":{"class":"json_input", option:departments.departments} } },
				          "employee.login.password":{div:{input:{"type":"password", size:"40"} } },
			            "number":{div:{input:{"type":"text", size:"6"} }},
				          "boolean":{div:{input:{"type":"checkbox"} }},
			            "CDATA":{div:{ input:null, textarea:{"class":"json_input", rows:"3", cols:"50"} }},
				          "default":{div:{span:{"class":"json_label"}, input:{"class":"json_input", "type":"text", size:"40"}, style:"float:left;" }}};

var EOL = {div:{style:"clear:both"}};

function patternResolver(aPattern, aName, aValue)
{
	var result = this.cascadePatternResolver(aPattern, aName, aValue);
	if (result)
	{
		this.populate(result, "div.id", aName);
		if (this.getValue(result, "div.span"))
		{
			if (!this.getValue(result, "div.span.text"))
			{
				var index = aName.lastIndexOf('.');
				var name = index > 0 ? aName.substring(index + 1) : aName;
				this.populate(result, "div.span.text", name + ":");
			}
		}
		var model = this.getValue(result, "div.select.option");
		if (model)
		{
			this.setValue(result, "div.select.name", aName);
			for (var i = 0; i < model.length; i++)
			{
				if (model[i].value === aValue)
				{
					this.setValue(model[i], "selected", true);
				}
			}
		}
		else
			if (this.getValue(result, "div.textarea"))
			{
				this.setValue(result, "div.textarea.name", aName);
				this.setValue(result, "div.textarea.text", aValue);
			}
			else
				if (this.getValue(result, "div.input"))
				{
					this.setValue(result, "div.input.name", aName);
					if (this.getValue(result, "div.input.type") == "checkbox" ||
					    this.getValue(result, "div.input.type") == "radio")
					{
						var value = this.getValue(result, "div.input.value") || "true";
						this.setValue(result, "div.input.value", value);
						if (("" + aValue) === ("" + value))
						{
							this.setValue(result, "div.input.checked", true);
							this.setValue(result, "div.input.defaultChecked", true);
						}
					}
					else
					{
						this.setValue(result, "div.input.value", aValue);
					}
				}
	}
	return result;
}

function parentNodeProvider(aPattern, aDocument, aName, aValue, aIndex)
{
	var newLine = false;
	if (this.getValue(aPattern, "div.textarea") || this.getValue(aPattern, "div.input.size") == "40" ||
	    aName === "employee.defaultActionID")
	{
		newLine = true;
	}
	var result = this.jsonToDOM(aPattern, aDocument);
	if (newLine)
	{
		var node = this.jsonToDOM(EOL, document);
		if ( !COMMONS.isArray(result) )
		{
			result = [result];
		}
		result.push(node);
	}
	return result;
}

function prepareForm()
{
	var form = document.getElementById("sample_form")
	if ( form )
	{
		if (form.elements.length < 1)
		{
			jTools.jsonToHTML(json, jPattern, patternResolver, form, parentNodeProvider);
		}
		else
		{
			var nodes = form.childNodes;
			if (nodes && form.length > 0)
			{
				var nLength = nodes.length;
				for (var i = 0; i < nLength; i++)
				{
					form.removeChild(form.firstChild);
				}
			}
		}
	}
}

function wrapResult(aValue)	// wrap result for pretty print only !!!!
{
	var result = aValue === null ? aValue : {employee:aValue};
	return result;
}

function getXMLRepresentatiion()
{
	var tools = new Jsoner();
	tools.isAttribute = function(aName)
	{
		return this.isCDATA(aName) || this.isText(aName);
	};
	return tools.jsonToXML(json, true);
}

function getNameValueRepresentation()
{
	var tools = new Jsoner();
	tools.isAttribute = function(aName)
	{
		return this.isCDATA(aName) || this.isText(aName);
	};
	return tools.jsonToPathValue(json);
}

function atrConverter(aValue, aName)
{
	var result = aValue;
	if (aName === "companyID")
	{
		result = corpMap[aValue];
	}
	else
		if (aName === "departmentID")
		{
			result = deptMap[aValue];
		}
	return result;
}

function testPopulate()
{
	var frm = document.getElementById("sample_form");
	var start = new Date();
	for (var i = 0; i < 100; i++)
	{
		jTools.isEquals(json, jTools.populateFormToJson(frm, jTools.clone(json)));
	}
	return (new Date() - start) / 100 + "ms";
}


function testLookup()
{
	var start = new Date();
	for (var i = 0; i < 100; i++)
	{
		jTools.lookupAll(items, "*employee", {"contact.email":/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/});
	}
	return (new Date() - start) / 100 + "ms";
}

function testGet()
{
	var start = new Date();
	var tmp;
	for (var i = 0; i < 1000; i++)
	{
		tmp = jTools.getValue(json, "employee.roles[0].role");
	}
	return (new Date() - start) / 1000 + "ms";
}

function testSet()
{
	var start = new Date();
	for( var i =0; i<1000; i++)
	{
		jTools.setValue(json, "employee.roles["+ (i%4) + "'].role", i);
	}
	return (new Date() - start)/1000 + "ms";
}

function addCrossLink()
{
	json.employee.names.crosslink = json.employee;
  json.employee.address.crosslink = json.employee.address;	
}


function getDifference()
{
  var tools = new Jsoner();
	var json3 = tools.clone(json);
	tools.setValue( json3, "employee.gid", 105);
	tools.setValue( json3, "employee.roles", [{role:105}] );
	return tools.getDifference(json, json3);
}